package com.spark.stop;


import org.apache.catalina.connector.Connector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


@RestController
@SpringBootApplication
public class StopApplication {

	public static void main(String[] args) {
		SpringApplication.run(StopApplication.class, args);
	}

	@RequestMapping
	public String index(){
		return "OK";
	}

	/**
	 * 9     * 用于接受 shutdown 事件
	 * 10
	 */
	@Bean
	public GracefulShutdown gracefulShutdown() {
		return new GracefulShutdown();
	}

	@Bean
	public ServletWebServerFactory servletContainer() {
		TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
		tomcatServletWebServerFactory.addConnectorCustomizers(gracefulShutdown());
		return tomcatServletWebServerFactory;
	}

	private class GracefulShutdown implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> {
		private volatile Connector connector;
		private final int waitTime = 10;

		@Override
		public void customize(Connector connector) {
			this.connector = connector;
		}

		@Override
		public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
			this.connector.pause();
			Executor executor = this.connector.getProtocolHandler().getExecutor();
			try {
				if (executor instanceof ThreadPoolExecutor) {
					ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
					threadPoolExecutor.shutdown();
					if (!threadPoolExecutor.awaitTermination(waitTime, TimeUnit.SECONDS)) {
						System.out.println("Tomcat 进程在" + waitTime + " 秒内无法结束，尝试强制结束");
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				Thread.currentThread().interrupt();
			}
		}
	}

}
